/*
******************************************************************************************
**
**  Copyright (C) 2011, Fujian WITSI Micro-electronic Tech. CO.,LTD., All Rights Reserved.
**
******************************************************************************************
*/
/*
******************************************************************************************
**
**	File: apitrans.c
**
**	Brief:
**
**	Logs:
**		2012.12.26		Created by ttlc
**
******************************************************************************************
*/
#include <stdint.h>
#include "sys_cmd.h"
#include "apitrans.h"

/*
******************************************************************************************
**	local referenced extern function and variables 
******************************************************************************************
*/
extern fn_cmd_api_t *g_cmd_api_hook;

/*
******************************************************************************************
**	local referenced macro defines & type defines
******************************************************************************************
*/

/*
******************************************************************************************
**	local function prototype
******************************************************************************************
*/
static int inited = 0;
static fn_cmd_api_t *g_cmd_api[CMD_ALL-CMD_MIN_NUM];// = {};

/*
******************************************************************************************
**	global variables 
******************************************************************************************
*/

/*
******************************************************************************************
**	Implementation functions 
******************************************************************************************
*/
int cmd_api_register(api_cmd_t cmd, fn_cmd_api_t *pcmd_func)
{
	if((cmd < CMD_MIN_NUM) || (cmd >= CMD_ALL) || (!pcmd_func))
    {
		return -ERR_PARAM;
    }
	if(!inited) 
    {
		inited = 1;
		memset(g_cmd_api, 0, sizeof(g_cmd_api));
	}
	g_cmd_api[GET_CMD_INDEX(cmd)] = pcmd_func;
	return cmd;
}

#define FIREWARE_VERSION	"API-V0.0.1"
#define FW_API_VER_INFO		(FIREWARE_VERSION " Build: " __DATE__ " " __TIME__)
static int api_get_version(unsigned char *cmd, int len)
{
	int resplen;
	resplen =strlen(FW_API_VER_INFO) + 1;
	memcpy(cmd, (unsigned char *)&resplen, sizeof (int));
	memcpy(cmd + sizeof (int), (unsigned char *)&resplen, sizeof (int));
	memcpy(cmd + sizeof(int) + sizeof (int),FW_API_VER_INFO, resplen);
	resplen += sizeof (int) + sizeof (int);
	return resplen;
}

/*
** RETURN:
**	>0: package length, package in the cmd buffer
**	=0: ok and nothing to respone
**	<0: error code while excusive cmd
*/
 int cmd_api_hook(unsigned char *buf, int len)
{
	int ret = -ERR_UNSUPPORT;
    unsigned char cmd = *buf;
	if((cmd >= CMD_MIN_NUM) && (cmd < CMD_ALL)) {
		cmd = GET_CMD_INDEX(cmd);
	    if(g_cmd_api[cmd]) 
	    {
		    ret = g_cmd_api[cmd](buf+1, len-1);
		    if(ret < 0) {
				memcpy(buf+1, (unsigned char *)&ret, sizeof(int));
				ret = sizeof(int);
		    }
	    }
	}
	return ret;
}

extern apitrans_t __apitrans_entry_start[], __apitrans_entry_end[];
int apitrans_init(void)
{
	apitrans_t *call;
	g_cmd_api_hook = cmd_api_hook;
	cmd_api_register(CMD_GET_FW_VER, api_get_version);

	for (call = __apitrans_entry_start; call < __apitrans_entry_end; call++) {
		(*call)();
	}
}

